package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CategoryClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CategoryBasicDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.QuestionAdminPageQuery;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author 老李头儿
 * @since 2025-03-27
 */
@Service
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final IInteractionReplyService replyService;
    private final UserClient userClient;
    private final CourseClient courseClient;
    private final SearchClient searchClient;
    private final CatalogueClient catalogueClient;
    private final CategoryClient categoryClient;

    /**
     * 根据id查询问题详情
     *
     * @param id
     * @return
     */
    @Override
    public QuestionVO queryQuestionById(Long id) {
        InteractionQuestion interactionQuestion = this.getById(id);

        QuestionVO vo = BeanUtil.toBean(interactionQuestion, QuestionVO.class);

        //填充缺失属性
        if (!vo.getAnonymity()) {
            UserDTO userDTO = userClient.queryUserById(interactionQuestion.getUserId());
            vo.setUserName(userDTO.getName());
            vo.setUserIcon(userDTO.getIcon());
        }
        return vo;
    }

    /**
     * 根据id删除当前用户问题
     *
     * @param id
     */
    @Override
    @Transactional
    public void deleteById(Long id) {
        //查询该问题
        InteractionQuestion interactionQuestion = this.getById(id);
        if (ObjectUtil.isEmpty(interactionQuestion)) {
            return;
        }
        //判断该问题是否属于当前用户
        if (ObjectUtil.notEqual(interactionQuestion.getUserId(), UserContext.getUser())) {
            throw new BadRequestException("只能删除自己的问题");
        }
        //删除问题及回复
        this.removeById(id);
        replyService.lambdaUpdate().eq(InteractionReply::getQuestionId, id).remove();
    }

    /**
     * 管理端分页查询互动问题
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {
        List<Long> courseIds = null;

        if (ObjectUtil.isNotEmpty(query.getCourseName())) {
            //根据课程名称获取课程id
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
        }


        //分页查询列表
        Page<InteractionQuestion> page = this.lambdaQuery()
                .in(query.getCourseName() != null, InteractionQuestion::getCourseId, courseIds)
                .eq(query.getStatus() != null, InteractionQuestion::getStatus, query.getStatus())
                .ge(query.getBeginTime() != null, InteractionQuestion::getCreateTime, query.getBeginTime())
                .le(query.getEndTime() != null, InteractionQuestion::getCreateTime, query.getEndTime())
                .page(query.toMpPage());

        List<InteractionQuestion> records = page.getRecords();

        if (ObjectUtil.isEmpty(records)) {
            return PageDTO.empty(page);
        }

        //查询课程信息并转为map
        Set<Long> userIds = records.stream().map(InteractionQuestion::getUserId).collect(Collectors.toSet());
        //根据用户id查询用户信息
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        //转为map
        if (ObjectUtil.isEmpty(userDTOS)) {
            throw new BadRequestException("询用户信息失败");
        }
        Map<Long, UserDTO> userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));

        //根据课程id查询课程信息
        List<CourseSimpleInfoDTO> simpleInfos = courseClient.getSimpleInfoList(courseIds);
        //转为map
        Map<Long, CourseSimpleInfoDTO> courseMap = simpleInfos.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, Function.identity()));

        //收集所有章id与节id
        HashSet<Long> chapterAndSectionIds = new HashSet<>();
        for (InteractionQuestion record : records) {
            if (ObjectUtil.isNotEmpty(record.getChapterId())) {
                chapterAndSectionIds.add(record.getChapterId());
            }
            if (ObjectUtil.isNotEmpty(record.getSectionId())) {
                chapterAndSectionIds.add(record.getSectionId());
            }
        }
        //查询章节与节信息
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(chapterAndSectionIds);
        if (ObjectUtil.isEmpty(cataSimpleInfoDTOS)) {
            throw new BadRequestException("查询章节与节信息失败");
        }
        //转为map
        Map<Long, CataSimpleInfoDTO> cataMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, Function.identity()));

        //查询分有分类
        List<CategoryBasicDTO> categoryBasicDTOS = categoryClient.getAllOfOneLevel();
        //转为map
        Map<Long, CategoryBasicDTO> categoryMap = categoryBasicDTOS.stream().collect(Collectors.toMap(CategoryBasicDTO::getId, Function.identity()));

        ArrayList<QuestionAdminVO> questionAdminVOS = new ArrayList<>();
        //遍历并填充属性
        for (InteractionQuestion record : records) {
            QuestionAdminVO questionAdminVO = BeanUtil.toBean(record, QuestionAdminVO.class);
            //填充提问者名称
            questionAdminVO.setUserName(userMap.get(record.getUserId()).getName());
            //填充课程名称
            CourseSimpleInfoDTO course = courseMap.get(record.getCourseId());
            questionAdminVO.setCourseName(course.getName());
            //填充章节名称
            questionAdminVO.setChapterName(cataMap.get(record.getChapterId()).getName());
            questionAdminVO.setSectionName(cataMap.get(record.getSectionId()).getName());
            //填充三级分类名称
            String categoryName = "";
            if (ObjectUtil.isNotEmpty(course.getThirdCateId())) {
                categoryName = categoryMap.get(course.getThirdCateId()).getName();
            }
            if (ObjectUtil.isNotEmpty(course.getSecondCateId())) {
                categoryName = categoryMap.get(course.getSecondCateId()).getName() + "/" + categoryName;
            }
            if (ObjectUtil.isNotEmpty(course.getFirstCateId())) {
                categoryName = categoryMap.get(course.getFirstCateId()).getName() + "/" + categoryName;
            }
            questionAdminVO.setCategoryName(categoryName);
            questionAdminVOS.add(questionAdminVO);
        }
        return PageDTO.of(page, questionAdminVOS);
    }

    /**
     * 管理端隐藏或显示问题
     *
     * @param id
     * @param hidden
     */
    @Override
    public void updateHidden(Long id, boolean hidden) {
        boolean update = this.lambdaUpdate()
                .eq(InteractionQuestion::getId, id)
                .set(InteractionQuestion::getHidden, hidden)
                .update();

        if (!update) {
            throw new BadRequestException("更新是否隐藏失败");
        }
    }

    /**
     * 管理端根据id查询问题详情
     *
     * @param id
     */
    @Override
    public QuestionAdminVO getQuestionDetail(Long id) {
        //查询数据库
        InteractionQuestion question = this.lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .one();
        if (ObjectUtil.isEmpty(question)) {
            throw new BadRequestException("查询问题失败");
        }
        //属性拷贝
        QuestionAdminVO questionAdminVO = BeanUtil.toBean(question, QuestionAdminVO.class);

        //查询提问者信息
        UserDTO userDTO = userClient.queryUserById(question.getUserId());
        //填充提问者信息
        questionAdminVO.setUserName(userDTO.getName());
        questionAdminVO.setUserIcon(userDTO.getIcon());

        //填充课程信息
        CourseFullInfoDTO courseInfoById = courseClient.getCourseInfoById(question.getCourseId(), true, true);
        questionAdminVO.setCourseName(courseInfoById.getName());
        //获取老师Id
        List<Long> teacherIds = courseInfoById.getTeacherIds();
        //根据老师id查询老师信息
        List<UserDTO> userDTOS = userClient.queryUserByIds(teacherIds);
        String teacherNames = null;
        if (ObjectUtil.isNotEmpty(userDTOS)) {
            teacherNames = userDTOS.stream()
                    .map(UserDTO::getName)
                    .collect(Collectors.joining(" "));
        }
        questionAdminVO.setTeacherName(teacherNames);
        //设置章和节信息
        HashSet<Long> set = new HashSet<>();
        if (ObjectUtil.isNotEmpty(question.getChapterId())) {
            set.add(question.getChapterId());
        }
        if (ObjectUtil.isNotEmpty(question.getSectionId())) {
            set.add(question.getSectionId());
        }
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(set);
        //转为map
        Map<Long, CataSimpleInfoDTO> cataMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, Function.identity()));
        if (ObjectUtil.isNotEmpty(cataMap)) {
            if (ObjectUtil.isNotEmpty(question.getChapterId())) {
                questionAdminVO.setChapterName(cataMap.get(question.getChapterId()).getName());
            }
            if (ObjectUtil.isNotEmpty(question.getSectionId())) {
                questionAdminVO.setSectionName(cataMap.get(question.getSectionId()).getName());
            }
        }
        //设置三级分类信息
        //查询分有分类
        List<CategoryBasicDTO> categoryBasicDTOS = categoryClient.getAllOfOneLevel();
        //转为map
        Map<Long, CategoryBasicDTO> categoryMap = categoryBasicDTOS.stream().collect(Collectors.toMap(CategoryBasicDTO::getId, Function.identity()));

        String categoryName = "";
        if (ObjectUtil.isNotEmpty(courseInfoById.getThirdCateId())) {
            categoryName = categoryMap.get(courseInfoById.getThirdCateId()).getName();
        }
        if (ObjectUtil.isNotEmpty(courseInfoById.getSecondCateId())) {
            categoryName = categoryMap.get(courseInfoById.getSecondCateId()).getName() + "/" + categoryName;
        }
        if (ObjectUtil.isNotEmpty(courseInfoById.getFirstCateId())) {
            categoryName = categoryMap.get(courseInfoById.getFirstCateId()).getName() + "/" + categoryName;
        }
        questionAdminVO.setCategoryName(categoryName);

        //更新问题状态为已查看
        if (question.getStatus() != 1) {
            this.lambdaUpdate()
                    .eq(InteractionQuestion::getId, id)
                    .set(InteractionQuestion::getStatus, 1)
                    .update();
        }
        return questionAdminVO;
    }

    /**
     * 新增提问
     *
     * @param questionDTO
     */
    @Override
    public void saveQuestion(QuestionFormDTO questionDTO) {
        //属性拷贝
        InteractionQuestion interactionQuestion = BeanUtil.toBean(questionDTO, InteractionQuestion.class);
        //设置userId
        interactionQuestion.setUserId(UserContext.getUser());
        //保存数据库
        save(interactionQuestion);
    }

    /**
     * 修改问题
     *
     * @param id
     */
    @Override
    public void updateQuestion(Long id, QuestionFormDTO questionDTO) {
        //属性拷贝
        InteractionQuestion interactionQuestion = BeanUtil.toBean(questionDTO, InteractionQuestion.class);
        //设置Id
        interactionQuestion.setId(id);
        //修改数据库表
        updateById(interactionQuestion);
    }

    /**
     * 分页查询问题
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionVO> pageQuestions(QuestionPageQuery query) {
        // 1.参数校验，课程id和小节id不能都为空
        Long courseId = query.getCourseId();
        Long sectionId = query.getSectionId();
        if (courseId == null && sectionId == null) {
            throw new BadRequestException("课程id和小节id不能都为空");
        }
        // 2.分页查询
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, info -> !info.getProperty().equals("description"))
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, UserContext.getUser())
                .eq(courseId != null, InteractionQuestion::getCourseId, courseId)
                .eq(sectionId != null, InteractionQuestion::getSectionId, sectionId)
                .eq(InteractionQuestion::getHidden, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 3.根据id查询提问者和最近一次回答的信息
        Set<Long> userIds = new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        // 3.1.得到问题当中的提问者id和最近一次回答的id
        for (InteractionQuestion q : records) {
            if (!q.getAnonymity()) { // 只查询非匿名的问题
                userIds.add(q.getUserId());
            }
            answerIds.add(q.getLatestAnswerId());
        }
        // 3.2.根据id查询最近一次回答
        answerIds.remove(null);
        Map<Long, InteractionReply> replyMap = new HashMap<>(answerIds.size());
        if (CollUtils.isNotEmpty(answerIds)) {
            List<InteractionReply> replies = replyService.listByIds(answerIds);
            for (InteractionReply reply : replies) {
                replyMap.put(reply.getId(), reply);
                if (!reply.getAnonymity()) { // 匿名用户不做查询
                    userIds.add(reply.getUserId());
                }
            }
        }

        // 3.3.根据id查询用户信息（提问者）
        userIds.remove(null);
        Map<Long, UserDTO> userMap = new HashMap<>(userIds.size());
        if (CollUtils.isNotEmpty(userIds)) {
            List<UserDTO> users = userClient.queryUserByIds(userIds);
            userMap = users.stream()
                    .collect(Collectors.toMap(UserDTO::getId, u -> u));
        }

        // 4.封装VO
        List<QuestionVO> voList = new ArrayList<>(records.size());
        for (InteractionQuestion r : records) {
            // 4.1.将PO转为VO
            QuestionVO vo = BeanUtils.copyBean(r, QuestionVO.class);
            vo.setUserId(null);
            voList.add(vo);
            // 4.2.封装提问者信息
            if (!r.getAnonymity()) {
                UserDTO userDTO = userMap.get(r.getUserId());
                if (userDTO != null) {
                    vo.setUserId(userDTO.getId());
                    vo.setUserName(userDTO.getName());
                    vo.setUserIcon(userDTO.getIcon());
                }
            }

            // 4.3.封装最近一次回答的信息
            InteractionReply reply = replyMap.get(r.getLatestAnswerId());
            if (reply != null) {
                vo.setLatestReplyContent(reply.getContent());
                if (!reply.getAnonymity()) {// 匿名用户直接忽略
                    UserDTO user = userMap.get(reply.getUserId());
                    vo.setLatestReplyUser(user.getName());
                }

            }
        }

        return PageDTO.of(page, voList);
    }

}
